package grabber;

import jxl.write.WriteException;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User: Vladimir
 * Date: 12.11.12 Time: 20:50
 */
public class TelegorodGrabber {
    public static final int TIMEOUT = 20000;
    public static final String BASE_URL = "http://www.telegorod.ru";
    public static final String XLS_PATH = "data/test/phone/";
    public static final String IMG_PATH = "images/phone/";
    public static final Pattern pattern = Pattern.compile("\\d+");

    public static void main(String[] args) throws IOException, WriteException {
//        List<String> brands = new ArrayList<String>();
//        brands.add("Nokia");
//        brands.add("HTC");
//        brands.add("Sony");
//        brands.add("SonyEricsson");
//        brands.add("Samsung");
        String url = BASE_URL + "/mobile/";
        Document doc = Jsoup.connect(url).timeout(TIMEOUT).get();
        Elements items = doc.select("div.content div.tradeItems");
        Map<String, List<Phone>> phonesByBrand = new TreeMap<String, List<Phone>>();
//        List<Phone> phones = new ArrayList<Phone>();
        for (Element item : items) {
            Phone phone = new Phone();
            Element itemTitle = item.select("a.itemTitle").get(0);
            String link = itemTitle.attr("href");
            String name = itemTitle.attr("title").replace("SonyEricsson", "Sony Ericsson");
            phone.name = name;
            String brand = name.split("\\s")[0];
            String price = item.select("div.tiePrice div").text();
            phone.price = parsePrice(price);

            doc = Jsoup.connect(BASE_URL + link).timeout(TIMEOUT).get();

            Elements imgs = doc.select("div.myPriceBlock div.itemImgs a");
            int count = 0;
            for (Element img : imgs) {
                count++;
                String imgUrl = BASE_URL + img.attr("onClick").split("'")[1];
                String countStr = count > 1 ? count + "" : "";
                String imgPath = IMG_PATH + "phone " + name.toLowerCase() + countStr + ".jpg";
                saveImage(imgUrl, imgPath);
            }

            phone.techData = filterHtml(doc.select("td.techInfo noindex").get(0).html());
            phone.descData = filterHtml(doc.select("div.itemBody div tr[valign=top] td div").get(0).html());
            phone.descData = "<p>Раздел наполняется.</p>";

//            System.out.println(phone.name + " " + phone.price + " " + phone.techData.length() + " " + phone.descData.length());
//            phones.add(phone);
            if (phonesByBrand.containsKey(brand)) {
                List<Phone> phones = phonesByBrand.get(brand);
                phones.add(phone);
            } else {
                List<Phone> phones = new ArrayList<Phone>();
                phones.add(phone);
                phonesByBrand.put(brand, phones);
            }
        }
        saveToXls(phonesByBrand);
    }

    private static void saveImage(String imgUrl, String path) throws IOException {
        System.out.println(path);
        URL url = new URL(imgUrl);
        InputStream in = url.openStream();
        OutputStream out = new BufferedOutputStream(new FileOutputStream(path));
        for (int b; (b = in.read()) != -1;) {
            out.write(b);
        }
        out.close();
        in.close();
    }

    private static String filterHtml(String html) {
        html = html.replaceAll("style=\"padding:1px 4px;font-size:11px\"", "");
        html = html.replaceAll("&nbsp;", " ");
        html = html.replaceAll("class=\"techInfoDotted\"", "");
        html = html.replaceAll("#fbf6b6", "#faf7e6");
        html = html.replaceAll("<img.+/>", "<p style=\"font-weight:bold\">Да</p>");
        html = html.replaceAll(";", ",");
        return html;
    }

    private static void saveToXls(Map<String, List<Phone>> phonesByBrand) throws IOException, WriteException {
        HSSFWorkbook wb = new HSSFWorkbook();
        FileOutputStream fileOut = new FileOutputStream(XLS_PATH + "phone.xls");
        for (String brand : phonesByBrand.keySet()) {
            HSSFSheet sheet = wb.createSheet(brand);
            printHeader(sheet);
            printCategory(sheet);
            printCategoryByBrand(sheet, brand);
            int row = 3;
            for (Phone phone : phonesByBrand.get(brand)) {
                int column = 0;
                HSSFRow newRow = sheet.createRow(row);    
                newRow.createCell(column++).setCellValue(brand);
                newRow.createCell(column++).setCellValue(phone.name.replace(brand, "").trim());
                newRow.createCell(column++).setCellValue(0);
                newRow.createCell(column++).setCellFormula(String.format("\"Phone \"&A%s&\" \"&B%s", row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("\"Мобильный телефон \"&A%s&\" \"&B%s", row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("LOWER(\"Phone_\"&SUBSTITUTE(A%s,\" \",\"_\")&\"_\"&SUBSTITUTE(B%s,\" \",\"_\"))", row + 1, row + 1));
                newRow.createCell(column++).setCellValue(phone.price);
                newRow.createCell(column++).setCellValue(phone.price);
                newRow.createCell(column++).setCellValue(0);
                newRow.createCell(column++).setCellFormula(String.format("\"<div class=\"\"cpt_category_tree\"\">Что еще покупают с телефоном \"&A%s&\" \"&B%s&\": ${item.order.list}</div><h2>Характеристики телефона \"&A%s&\" \"&B%s&\"</h2> \"&R%s&\"<h2>Описание мобильного телефона \"&A%s&\" \"&B%s&\".</h2> \"&S%s&\"<h2>Гарантия на мобильный телефон \"&A%s&\" \"&B%s&\".</h2> \"&T%s&\"<h3>Доставка телефона \"&A%s&\" \"&B%s&\".</h3> #{common.make-order} #{common.shipping} #{common.ad-text}\"", row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("\"<h2>Купить мобильный телефон \"&A%s&\" \"&B%s&\"</h2>\"", row + 1, row + 1));
                newRow.createCell(column++).setCellValue("");
                newRow.createCell(column++).setCellFormula(String.format("\"<h2>Купить мобильный телефон \"&A%s&\" \"&B%s&\"</h2>\"", row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("\"Купить мобильный телефон \"&A%s&\" \"&B%s&\"\"", row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("\"Купить мобильный телефон \"&A%s&\" \"&B%s&\"\"", row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("LOWER(D%s&\"-medium.jpg,\"&D%s&\"-small.jpg,\"&D%s&\"-large.jpg\")", row + 1, row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("LOWER(D%s&\"1-medium.jpg,\"&D%s&\"1-small.jpg,\"&D%s&\"1-large.jpg\")", row + 1, row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("LOWER(D%s&\"2-medium.jpg,\"&D%s&\"2-small.jpg,\"&D%s&\"2-large.jpg\")", row + 1, row + 1, row + 1));
                newRow.createCell(column++).setCellFormula(String.format("LOWER(D%s&\"3-medium.jpg,\"&D%s&\"3-small.jpg,\"&D%s&\"3-large.jpg\")", row + 1, row + 1, row + 1));
                newRow.createCell(column++).setCellValue(phone.techData);
                newRow.createCell(column++).setCellValue(phone.descData);
                newRow.createCell(column++).setCellValue("<p>Все мобильные телефоны имеют официальные сертификаты производителя и фирменную гарантию - 12 месяцев!</p>");
                row++;
            }
        }
        wb.write(fileOut);
        fileOut.close();
    }

    private static void printCategory(HSSFSheet sheet) {
        int column = 0;
        HSSFRow row = sheet.createRow(1);
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("Phones");
        row.createCell(column++).setCellValue("Мобильные телефоны");
        row.createCell(column++).setCellValue("phones");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("<h2>Купить мобильный телефон #{common.region}</h2>");
        row.createCell(column++).setCellValue("<h2>Купить мобильный телефон #{common.region}</h2>");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("Купить мобильные телефоны Nokia Нокиа Samsung Самсунг Sony HTC LG Iphone в интернет-магазине");
        row.createCell(column++).setCellValue("Купить мобильные телефоны Nokia Нокиа Samsung Самсунг Sony HTC LG Iphone в интернет-магазине");
        row.createCell(column++).setCellValue("Купить мобильные телефоны Nokia Нокиа Samsung Самсунг Sony HTC LG Iphone в интернет-магазине по лучшим ценам. Звоните #{common.phone-shop}");
        row.createCell(column++).setCellValue("phones.jpg");
    }
    
    private static void printCategoryByBrand(HSSFSheet sheet, String brand) {
        int column = 0;
        HSSFRow row = sheet.createRow(2);
        row.createCell(column++).setCellValue(brand);
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellFormula("\"!Phones \"&A3");
        row.createCell(column++).setCellFormula("\"!Мобильные телефоны \"&A3");
        row.createCell(column++).setCellFormula("LOWER(\"Phones_\" &SUBSTITUTE(A3,\" \",\"_\"))");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellFormula("\"<h2>Купить мобильный телефон \"&A3&\" #{common.region}</h2>\"");
        row.createCell(column++).setCellFormula("\"Купить мобильный телефон \"&A3&\" #{common.region}\"");
        row.createCell(column++).setCellValue("");
        row.createCell(column++).setCellFormula("\"Купить мобильный телефон \"&A3&\" #{common.region}\"");
        row.createCell(column++).setCellFormula("\"Купить мобильный телефон \"&A3&\" #{common.region}\"");
        row.createCell(column++).setCellFormula("\"Купить мобильный телефон \"&A3&\" #{common.region} по лучшим ценам. Звоните #{common.phone-shop}\"");
        row.createCell(column++).setCellValue("");
    }

/*
    private static void saveToXlsOld(Map<String, List<Phone>> phonesByBrand) throws IOException, WriteException {
        WorkbookSettings s = new WorkbookSettings();
        s.setLocale(new Locale("ru", "RU"));
        for (String brand : phonesByBrand.keySet()) {
            File xlsFile = new File(XLS_PATH + "phone." + brand + ".xls");
            WritableWorkbook workbook = Workbook.createWorkbook(xlsFile, s);
            WritableSheet sheet = workbook.createSheet("List 1", 0);
            printHeader(sheet);
            System.out.println(brand + ": ");
            int row = 1;
            for (Phone phone : phonesByBrand.get(brand)) {
                int column = 0;
                WritableCell cell = new Label(column++, row, brand);
                sheet.addCell(cell);
                cell = new Label(column++, row, phone.name.replace(brand, "").trim());
                sheet.addCell(cell);
                cell = new Number(column++, row, 0);
                sheet.addCell(cell);
                cell = new Formula(column++, row, String.format("Phone &A%s& &B%s", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Formula(column++, row, String.format("Телефон &A%s& &B%s", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=СТРОЧН(\"Phone_\" &ПОДСТАВИТЬ(A%s;\" \";\"_\") & \"_\" & ПОДСТАВИТЬ(B%s;\" \";\"_\"))", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Number(column++, row, phone.price);
                sheet.addCell(cell);
                cell = new Number(column++, row, phone.price);
                sheet.addCell(cell);
                cell = new Number(column++, row, 0);
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=\"<div class=\"\"cpt_category_tree\"\">Что еще покупают с телефоном \"&A%s&\" \"&B%s&\": ${item.order.list}</div><h2>Характеристики телефона \"&A%s&\" \"&B%s&\"</h2> \"&R%s&\"<h2>Описание телефона \"&A%s&\" \"&B%s&\".</h2> \"&S%s&\"<h3>Доставка телефона \"&A%s&\" \"&B%s&\".\"", row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=\"<h2>Купить мобильный телефон \"&A%s&\" \"&B%s&\"</h2>\"", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, "${sort}");
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=\"<h2>Купить мобильный телефон \"&A%s&\" \"&B%s&\"</h2>\"", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=\"Купить мобильный телефон \"&A%s&\" \"&B%s&\"\"", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=\"Купить мобильный телефон \"&A%s&\" \"&B%s&\"\"", row + 1, row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=СТРОЧН(D%s)", row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, String.format("=СТРОЧН(D%s)&1", row + 1));
                sheet.addCell(cell);
                cell = new Label(column++, row, phone.techData);
                sheet.addCell(cell);
                cell = new Label(column++, row, phone.descData);
                sheet.addCell(cell);
                System.out.println(phone.name);
                row++;
            }
            workbook.write();
            workbook.close();
        }
    }
*/

    private static void printHeader(HSSFSheet sheet) throws WriteException {
        int column = 0;
        HSSFRow row = sheet.createRow(0);
        row.createCell(column++).setCellValue("Бренд");
        row.createCell(column++).setCellValue("Модель");
        row.createCell(column++).setCellValue("Артикул");
        row.createCell(column++).setCellValue("Наименование (English)");
        row.createCell(column++).setCellValue("Наименование (Русский)");
        row.createCell(column++).setCellValue("ID страницы (часть URL используется в ссылках на эту страницу)");
        row.createCell(column++).setCellValue("Цена");
        row.createCell(column++).setCellValue("Старая цена");
        row.createCell(column++).setCellValue("На складе");
        row.createCell(column++).setCellValue("Описание (Русский)");
        row.createCell(column++).setCellValue("Краткое описание (Русский)");
        row.createCell(column++).setCellValue("Сортировка");
        row.createCell(column++).setCellValue("Заголовок страницы (Русский)");
        row.createCell(column++).setCellValue("Тег META keywords (Русский)");
        row.createCell(column++).setCellValue("Тег META description (Русский)");
        row.createCell(column++).setCellValue("Фотография");
        row.createCell(column++).setCellValue("Фотография");
        row.createCell(column++).setCellValue("Фотография");
        row.createCell(column++).setCellValue("Фотография");
        row.createCell(column++).setCellValue("Характеристики");
        row.createCell(column++).setCellValue("Художественное описание");
        row.createCell(column++).setCellValue("Гарантия");
    }
    
/*
    private static void printHeader(WritableSheet sheet) throws WriteException {
        int column = 0;
        int row = 0;
        WritableCell cell = new Label(column++, row, "Бренд");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Модель");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Артикул");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Наименование (English)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Наименование (Русский)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "ID страницы (часть URL используется в ссылках на эту страницу)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Цена");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Старая цена");
        sheet.addCell(cell);
        cell = new Label(column++, row, "На складе");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Описание (Русский)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Краткое описание (Русский)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Сортировка");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Заголовок страницы (Русский)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Тег META keywords (Русский)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Тег META description (Русский)");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Фотография");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Фотография");
        sheet.addCell(cell);
        cell = new Label(column++, row, "Характеристики");
        sheet.addCell(cell);
        cell = new Label(column, row, "Художественное описание");
        sheet.addCell(cell);
    }
*/

    private static int parsePrice(String price) {
        Matcher matcher = pattern.matcher(price);
        String parsedPrice = "";
        while (matcher.find()) {
            parsedPrice = parsedPrice + matcher.group();
        }
        try {
            return Integer.parseInt(parsedPrice);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    static class Phone {
        String name;
        String techData;
        String descData;
        int price;
    }
}
